/**
 * <p>zxt.ui.Select和zxt.ui.Combobox的基类</p>
 * @class
 * @extends zxt.ui.AbstractSelect zxt.ui.Element
 * @param {Boolean} labelonly 是否只显示标签 默认是true 
 */
zxt.ui.SelectBase = function(labelonly){
	zxt.ui.AbstractSelect.call(this);
	zxt.ui.Element.call(this);
	
	this._elem = null;
	this._defer = false;
	
	this.$Intelligent = true;

	this._hoverTimer = 0;
	this._showing = false;
	
	this._suggestionsKey = 'combobox_suggestions';
	this._optionsContainer;
	this._oriValue = '';
	this._selIndex = 0;
	this._oldVal;
	this._maxHeight;
	this._labelonly = labelonly==false?false:true;
	
	if(this._labelonly==false){
		this.$Format = "$VALUE$ $LABEL$";
	};
	
	this._overOpts = false;
	this._outOptHide = true;	
};

zxt.defineClazz(zxt.ui.SelectBase, zxt.ui.AbstractSelect, zxt.ui.Element);
zxt.ui.SelectBase.prototype.getSelfLabel = zxt.ui.AbstractSelect.prototype.getSelfLabel;
zxt.ui.SelectBase.prototype.conf = zxt.ui.AbstractSelect.prototype.conf;

/**
 * <p>定义快捷键属性：向上、向下、确定、TAB键、离开 </p>
 * @function
 */
zxt.ui.SelectBase.prototype._keys = { up: 38, down: 40, enter: 13, tab: 9, esc: 27 };	

/**
 * <p>如果参数有，效则设置最大高度；否则返回当前选项列表的最大长度</p>
 * @function
 * @param {int} v 高度设置
 * @return {int} 如果参数没有上送，则返回当前选项列表的最大长度
 */
zxt.ui.SelectBase.prototype.maxOptionsHeight = function(v){
	if(v===undefined){
		if ( zxt.util.isValue(this._maxHeight) ){
			return this._maxHeight;
		};	
		
		return this.maxHeight;
	};
	this._maxHeight = v;
};

/**
 * <p>渲染下拉表，并关联鼠标悬停方法</p>
 * @function 
 * @return
 */
zxt.ui.SelectBase.prototype._renderOptionsContainer = function(){
	var host = this;
	if(!this._optionsContainer) {
		var mh = this.maxOptionsHeight();
		if(zxt.util.isAvailable(mh)){
			this._optionsContainer = $("<ul class='optdrop' style='max-height:" + mh + ";'/>").appendTo(window.$('body'));

		}else{
			this._optionsContainer = $("<ul class='optdrop'/>").appendTo(window.$('body'));
		};

		if ($.fn.bgiframe)
			this._optionsContainer.bgiframe();
		
		this._optionsContainer.hover( function(){ host._onDropMouseover(); }, function() { host._onDropMouseout(); } );   
	}
};

/**
 * <p>鼠标移出范围事件</p>
 * @private
 * @function
 * 
 */
zxt.ui.SelectBase.prototype._onDropMouseout = function(){
	this._overOpts = false;	
	//if ( this._outOptHide )	this._hideOptions();
};	


/**
 * <p>鼠标移进范围事件</p>
 * @private
 * @function
 * 
 */
zxt.ui.SelectBase.prototype._onDropMouseover = function(){
	this._overOpts = true;	
	if (this._hoverTimer){
     window.clearTimeout(this._hoverTimer);
     this._hoverTimer = 0;
  };
};

/**
 * <p>下拉列表展开</p>
 * @param {DOM} tg DOM节点对象
 * @param {int} tm 设置收缩时间
 * @return
 */
zxt.ui.SelectBase.prototype._expandOptions = function(tg, tm){	
	var instance = this;
	var time = tm || 0;
	
	var wd = $(tg).width();
	this._optionsContainer.width(wd);		
	this._optionsContainer.show();
	zxt.util.dom.postionWithRel( this._optionsContainer.get(0), tg, false );  
	
	//this._optionsContainer.slideDown(100);
	//this._optionsContainer.show();
	this._showing = true;
	
	if ( this.$Intelligent && time>0 && (!this._hoverTimer)) {//超过时间设置，自动收缩
		this._hoverTimer = window.setTimeout(function() {instance._hideOptions();}, time);
	};	
};

/**
 * <p>收缩下拉列表</p>
 * @function
 * @return
 */
zxt.ui.SelectBase.prototype._hideOptions = function() {
	if (this._showing) {
		this._optionsContainer.hide().children('li').each(function() { $(this).remove(); });
		this._showing = false;
		this._hoverTimer = 0;
	};
};

/**
 * <p>键盘事件处理方法</p>
 * @function
 * @param {Event} evt 键盘事件
 * @return
 */
zxt.ui.SelectBase.prototype.keydown = function(evt) {
	var keys = this._keys;
	var instance = this;
	
	if(this.mode()=="DISABLE" || this.mode() == "READONLY"){
		evt.preventDefault();
		return;
	}
	
	switch (evt.keyCode) {
	case keys.esc://27
		this._hideOptions();
		evt.preventDefault();
		return;
	// case keys.enter://13
		// if(this._showing){
			// this.choose();		
		// } else {
			// this.show();
		// };		
		// evt.preventDefault();
		// return;
	case keys.up://38
		this.goup();
		window.clearTimeout(this._hoverTimer);
		this._hoverTimer = window.setTimeout(function() {instance._hideOptions();}, 2000);
		evt.preventDefault();
		return;
	case keys.down://40
		this.godown();
		window.clearTimeout(this._hoverTimer);
		this._hoverTimer = window.setTimeout(function() {instance._hideOptions();}, 2000);
		evt.preventDefault();
		return;
	}
};

/**
 * <p>向下键下拉列表渲染</p>
 * @function
 * @return
 */
zxt.ui.SelectBase.prototype.godown = function() {
	if (this._showing) {
		var options = this._optionsContainer.children('li');
		var n = options.size();
		if (!n)return;
		
		this._selIndex++;

		if (this._selIndex > n - 1)
			this._selIndex = 0;

		var v = options.eq(this._selIndex);
		
		if (this._selIndex == 0) {
			v.get(0).offsetParent.scrollTop = 0;
		};
		
		if (v.size()) {
			options.each(function() {
				$(this).removeClass('selected')
			});
			v.addClass('selected');
			if (v.get(0).clientHeight+v.get(0).offsetTop>v.get(0).offsetParent.clientHeight) {
				v.get(0).offsetParent.scrollTop += v.get(0).clientHeight;
			};
		}
	} else {
		var _options = this.options();
		var n = _options.length;
		if (!n)return;
		
		this._selIndex++;
	
		if (this._selIndex > n - 1)
			this._selIndex = 0;
	
		var v = _options[this._selIndex];
		
		this.choose();
	}
};

/**
 * <p>向上键下拉列表渲染</p>
 * @function
 * @return
 */
zxt.ui.SelectBase.prototype.goup = function() {
	if (this._showing) {
		var options = this._optionsContainer.children('li');
		var n = options.size();
		if (!n)return;
		this._selIndex--;

		if (this._selIndex < 0)
			this._selIndex = n - 1;

		var v = options.eq(this._selIndex);
		
		if (this._selIndex == n - 1) {
			v.get(0).offsetParent.scrollTop = v.get(0).offsetTop-v.get(0).offsetParent.clientHeight+v.get(0).clientHeight;
		};
		
		if (v.size()) {
			options.each(function() {
				$(this).removeClass('selected')
			});
			v.addClass('selected');
			if (v.get(0).offsetTop<v.get(0).offsetParent.scrollTop) {
				v.get(0).offsetParent.scrollTop -= v.get(0).clientHeight;
			};
		}
	} else {
		var _options = this.options();
		var n = _options.length;
		if (!n)return;
		
		this._selIndex--;
	
		if (this._selIndex < 0)
			this._selIndex = n - 1;
	
		
		
		this.choose();
	}
};


/**
 * <p>选择器失去焦点事件</p>
 * @function
 * @return
 */
zxt.ui.SelectBase.prototype._blur = function() {
	var instance = this;
	instance._hideOptions();	
	//if (!this._hoverTimer) {
		//this._hoverTimer = window.setTimeout(function(){instance._hideOptions()}, 1000);
	//}
	//去除隐藏时间
	
};

/**
 * <p>下拉框, 可以获取用户的选择</p>
 * 
 * @class 下拉框控件类
 * @param {Boolean} [labelonly] 是否只显示标签 默认是true 
 * @param {String} [listMaxHeight] 下拉列表的选项列表的最大长度，超过这个长度带滚动条，默认为没有限制。
 */
zxt.ui.Select = function(labelonly) {		
	zxt.ui.SelectBase.call(this,labelonly);
	
	this.$Required = false;
	this.$Intelligent = true;
	
	this._menuOption = new Array();
	this._current = null;
	this._childern = this._options;
	
	this._jqDom = null;	
	this._$titlePanel = null;	
	this._jqCur = null;

};

/**
 * <p>根据传入的DOM元素, 解析传入的相关属性, 创建相应的下拉选择框对象</p>
 * 
 * @function
 * @static
 * @param {DOM} elem 解析的DOM元素
 * @param {string} [zxt.labelonly] 是否只显示标签 默认是true 
 * @param {string} [zxt.options] 选项 格式为“选项1:选项1的值,选项2:选项2的值,选项3:选项3的值” 
 * @param {string} [zxt.service] 后台加载服务的名称 
 * @param {string} [zxt.method] 后台加载调用的函数名 
 * @param {string} [zxt.param] 后台加载函数的参数 
 * @param {string} [zxt.option] 选项的值 
 * @param {string} [zxt.label] 选项的标签 
 * @param {String} [zxt.maxHeight] 下拉列表的选项列表的最大长度，超过这个长度带滚动条，默认为没有限制。
 * @return {zxt.ui.Select} 根据传入的DOM元素创建的组合输入框对象
 */
zxt.ui.Select.parse = function(elem) {
	var j = $(elem);
	
	var _labelonly = j.attr("zxt.labelonly")=="false"? false:true;
	
	var _formatType = j.attr("zxt.formatType");
	
	var _instance = new zxt.ui.Select(_labelonly);
	
	var _req = j.attr("zxt.required");
	_instance.$Required = (_req === "true");
	
	var _value = j.attr("zxt.value");	
	if ( zxt.util.isValue(_value) )
		_instance.val(_value);
	
	var _maxHeight = j.attr("zxt.maxHeight");
	_instance._maxHeight = _maxHeight;
	
	if(!_instance._defer){
		var composite = zxt.data.parseOptions(elem);
		composite.loadToSelect(_instance);
	}
	_instance._elem = j.get(0).outerHTML;
	_instance.formatType(_formatType);
		
	return _instance;
};

zxt.defineClazz(zxt.ui.Select, zxt.ui.SelectBase);

/**
 * <p>返回控件类型</p>
 * 
 * @function
 * @returns {string} "zxt.ui.Select"
 */
zxt.ui.Select.prototype.getType = function() {
	return "zxt.ui.Select";
};

/**
 * <p>如果参数没上送，则返回当前的显示格式设置；否则，设置显示格式</p>
 * @param  {String} v 显示格式
 * @return {String} 如果参数没上送，则返回当前的显示格式设置
 */
zxt.ui.Select.prototype.formatType = function(f){
	if (zxt.util.isAvailable(f)) {this._formatType=f};
	return this._formatType;
}

/**
 * <p>验证值的合法性</p>
 * 
 * @function
 * @param {Object} value 待验证的值,该方法未使用该参数
 * @returns {boolean} 返回true
 */
zxt.ui.Select.prototype.validate = function(value) {
	var rs = [];
	if (!zxt.util.utilsFormat(this.val(),this.formatType())) {
		rs.push("utilsFormat error");
		this.validateStatus(false,zxt.core.ValidatorType.FORMAT,this.formatType());
	}
	return rs;
};

/**
 * <p>设置当前的选项</p>
 * @function
 * @param {Object} opt 选项参数设置
 * @return
 */
zxt.ui.Select.prototype.setCurrent = function(opt) {
	this._current = opt;
	this.val( this._current.value );
};


/**
 * <p>渲染下拉框</p>
 * @private
 * @function
 * @return
 */
zxt.ui.Select.prototype._renderSelect = function(){
	var instance = this;
	
	this._$titlePanel = new zxt.ui.TablePanel(1, 2);
	var _titlePanelDom = this._$titlePanel.render();
	$(_titlePanelDom).css("table-layout", "fixed");
	
	if(this.mode() == "DISABLE"){
		this._jqCur = $("<div class='zxt-SelectCurrent zxt-SelectDisable'></div>");
		var jqArrowInner = $("<span class='zxt-SelectArrow'><span>v</span></span>");
		var jqArrow = $("<div class='zxt-SelectArrowDiv'>").append(jqArrowInner);
	}else if (this.mode() == "READONLY") {
		this._jqCur = $("<div class='zxt-SelectCurrent '></div>");
		var jqArrowInner = $("<span class='zxt-SelectArrow'><span>v</span></span>");
		var jqArrow = $("<div class='zxt-SelectArrowDiv'>").append(jqArrowInner);
	}else{
		this._jqCur = $("<div class='zxt-SelectCurrent'></div>").click( function(){ instance._onSelectClick(); } );	
		var jqArrowInner = $("<span class='zxt-SelectArrow'><span>v</span></span>");
		var jqArrow = $("<div class='zxt-SelectArrowDiv'>").append(jqArrowInner).click( function(){ instance._onSelectClick(); } );
	};
	
	this._decorate();	
	
	$(this._$titlePanel.getCell(0, 0)).attr("width", "100%").append(this._jqCur);	
	$(this._$titlePanel.getCell(0, 1)).attr("width", "17px").append(jqArrow);
	this._jqDom.append(_titlePanelDom).append(this._jqList);
	
	var oldSuggestions = $.data(this._jqDom, this._suggestionsKey);
	$.data(this._jqDom, this._suggestionsKey, this._labels);

	// exit if already initialized
	if (oldSuggestions)
		return;
	
	this._jqDom.focus(function() {instance.onFocus();}).blur(function(){instance.onBlur();});
	this._jqDom.keydown(function(event){ instance.keydown(event);});
};
/**
 * <p>
 * 渲染该下拉框的DOM节点
 * </p>
 * 
 * @function
 * @return {DOM} 渲染成的DOM节点
 */
zxt.ui.Select.prototype.renderSelf = function() {
	var host = this;
	
	if ( this._jqDom == null ){
		this._jqDom = $("<div class='zxt-Select'tabindex='-1'>");
	} else {
		this._jqDom.empty();
	};
	
	this._createLabels();
	this._renderOptionsContainer();	
   
  var opt = this.getOptionByValue(this.val());
   
  var cur = opt;
	if ( zxt.util.notValue(cur) ){
		cur = this._options[0];		
	};
	if ( zxt.util.isValue( cur ) ){
		this.setCurrent(cur);	
	};

	this._renderSelect();
	return this._jqDom.get(0);
};

/**
 * <p>打开下拉框</p>
 * @function
 * @return
 */
zxt.ui.Select.prototype.show = function(){
	if(this.options()==null||this.options().length==0){
		var composite = zxt.data.parseOptions(this._elem);
		composite.loadToSelect(this);
		this.render();
	}
	
	var instance = this;	
	this._oriValue = this._jqCur.text();
	
	this._hideOptions();

	// generate the options (li inside ul)
	var html = '';
	var suggestions = $.data(this._jqDom, this._suggestionsKey);
	for ( var k in suggestions) {
		var v = suggestions[k];
		html += '<li>' + v + '</li>';
	}
	this._optionsContainer.html(html);
	
	// decide which option is currently selected	
	var found = false;
	var options = this._optionsContainer.children('li').each(
		function(i) {
			if (found)return;
			if ($(this).text().toLowerCase() == instance._oriValue.toLowerCase()) {
				$(this).addClass('selected');
				instance._selIndex = i;
				found = true;
			}
		});

	if (!options.size()) {
		return;
	};
	
	if (!found)options.eq(0).addClass('selected');
	options.hover(function() {
		options.each(function() {
			$(this).removeClass('selected');
		});
		$(this).addClass('selected');
		instance._selIndex = options.index(this);
	});

	var tt = function(opt, idx) {    
		this.onclick = function() {
			instance._onOptionClick(opt, idx);
		};
	};	
	for (i = 0; i != options.size(); i++) {		
		var opt = this._options[i];			
		var wa = new tt(opt, i);
		$(options[i]).click( wa.onclick );		
	};

	this._expandOptions(this._jqDom.get(0), 2000);	
};

/**
 * <p>设置当前的</p>
 * @return
 */
zxt.ui.Select.prototype._decorate = function() {	
	var iVal = this.val();	
	this._jqCur.removeClass("zxt-txmust");	
	if ( !zxt.util.isAvailable(iVal) ) {		
		if (this.$Required) {	
			this._jqCur.addClass("zxt-txmust");	
			this.validateStatus(false,zxt.core.ValidatorType.REQUIRED);
		}; 		
	}else{
		var errs = this.validate(iVal);	
		if (errs.length == 0) {
			this.validateStatus(true);
		}
	}
	
	var label = "";
	if ( zxt.util.isValue( this._current ) ){		
		label = this.getOptionText(this._current);
	};
	
	this._jqCur.text(label);
};	

zxt.ui.Select.prototype._onOptionClick = function(opt, idx){
	this.setCurrent(opt);
	this._decorate();	
	this._hideOptions();
};

/**
 * <p>显示选中的下拉列表某项内容</p>
 * @function
 * @return
 */
zxt.ui.Select.prototype.choose = function() {
	var _options = this.options();
	if(_options.length!=0){
		var v = _options[this._selIndex];
		this.setCurrent(v);
		this._decorate();	
	}
	this._hideOptions();	
};


/**
 * <p>打开或关闭下拉框</p>
 * @private
 * @function
 * 
 */
zxt.ui.Select.prototype._onSelectClick = function(){	
	if(this._showing){
		this._hideOptions();
	} else {
		this.show();
	};
	
	this.onFocus();
};	

/**
 * <p>获取选中项的值</p>
 * @function
 * @return
 */
zxt.ui.Select.prototype.beforeGetValue = function() {
	if(this.mode()=="MASK"||this.mode()=="LABEL"){
		return;
	}
	if ( zxt.util.isValue(this._current) ){
		this.val( this._current.value );
	};
};

/**
zxt.ui.Select.prototype.onKeyDown = function(event){
	var keyCode = event.keyCode;
	switch(keyCode){
		case 13:	
			this.show();
			break;
	};
}; **/

/**
 * <p>选择器获得焦点事件</p>
 * @private
 * @function
 * 
 */
zxt.ui.Select.prototype.whenFocus = function() {
	//this.show();	
	this._jqDom.addClass("zxt-SelectFocus");
};
/**
 * <p>选择器失去焦点事件</p>
 * @private
 * @function
 * 
 */
zxt.ui.Select.prototype.whenBlur = function() {
 	if ( this._overOpts || this._hoverTimer )
		 return;	
	this._blur();
	this._jqDom.removeClass("zxt-SelectFocus");
};

/**
 * <p>设置当前控件焦点</p>
 * 
 * @function
 *
 */
zxt.ui.Select.prototype.focusSelf = function(){
	this._jqDom.focus();
};

/**
 * <p>选择器失去焦点事件</p>
 * @private
 * @function
 * 
 */
zxt.ui.Select.prototype.blurSelf = function(){
	this._jqDom.blur();
};

/**
 * @class 下拉框工厂类
 */
zxt.ui.SelectFactory = function() {
	zxt.ui.InteractorFactory.call(this);
};

zxt.defineClazz(zxt.ui.SelectFactory, zxt.ui.InteractorFactory);

/**
 * <p>获取相应的下拉框实例对象</p>
 * 
 * @function
 * @return {zxt.ui.Select} 下拉框实例对象
 */
zxt.ui.SelectFactory.prototype.getInstance = function() {
	return new zxt.ui.Select();
};

/**
 * <p>组合输入框, 可以获取用户的选项或者输入项</p>
 * 
 * @class  组合输入框控件类
 * @param {Boolean} [required] 是否是必填项 默认为false
 * @param {Boolean} [chooseonly] 是否必须是已有选项 默认为false
 * @param {Boolean} [labelonly] 是否只显示标签 默认是true 
 */
zxt.ui.Combobox = function(required, chooseonly,labelonly) {
	zxt.ui.SelectBase.call(this,labelonly);
	
	this.$TextTransform = "uppercase";
	this.$MaxLength = null;
	this.$AutoComplete = 0;
	this.$RequireV = false;
	
	this._$jqDom = null;
	this._$input = null;

	this._autoShow = true;
	
	this._required = (required == true || required == "true");
	this._chooseonly = chooseonly;
	this._formatType = null;
	
	//this._outOptHide = false;
};


/**
 * <p>根据传入的DOM元素, 解析传入的相关属性, 创建相应的组合输入框对象</p>
 * 
 * @function
 * @static
 * @param {DOM} elem 解析的DOM元素
 * @param {string} [zxt.required] 是否是必填项 默认为false
 * @param {string} [zxt.chooseonly] 是否必须是已有选项 默认为false
 * @param {string} [zxt.labelonly] 是否只显示标签 默认是true
 * @param {string} [zxt.value] 设置默认值
 * @param {string} [zxt.options] 选项 格式为“选项1:选项1的值,选项2:选项2的值,选项3:选项3的值” 
 * @param {string} [zxt.service] 后台加载服务的名称 
 * @param {string} [zxt.method] 后台加载调用的函数名 
 * @param {string} [zxt.param] 后台加载函数的参数 
 * @param {string} [zxt.option] 选项的值 
 * @param {string} [zxt.label] 选项的标签 
 * @return {zxt.ui.Combobox} 根据传入的DOM元素创建的组合输入框对象
 */
zxt.ui.Combobox.parse = function(elem) {
	var j = $(elem);
	var _val = j.attr("zxt.value");
	var _required = j.attr("zxt.required");
	var _chooseonly = j.attr("zxt.chooseonly")=="true"?true:false;
	var _labelonly = j.attr("zxt.labelonly")=="false"? false:true;
	var _formatType = j.attr("zxt.formatType");
	
	var _instance = new zxt.ui.Combobox(_required, _chooseonly,_labelonly);
	_instance.val(_val);
	_instance.formatType(_formatType);
	
	var _autoShow = j.attr("zxt.autoShow")=="false"?false:true;
	_instance.autoShow(_autoShow);
	
	var _maxHeight = j.attr("zxt.maxHeight");
	_instance._maxHeight = _maxHeight;
	
	_instance._elem = j.get(0).outerHTML;
	
	if(!_instance._defer){
		var composite = zxt.data.parseOptions(elem);
		composite.loadToSelect(_instance);
	}
	return _instance;
};

zxt.defineClazz(zxt.ui.Combobox, zxt.ui.SelectBase);

/**
 * <p>返回控件类型</p>
 * 
 * @function
 * @returns {string} "zxt.ui.Combobox"
 */
zxt.ui.Combobox.prototype.getType = function() {
	return "zxt.ui.Combobox";
};

/**
 * <p>获取控件交互值</p>
 * @function
 * @return {String} 控件交互值
 */
zxt.ui.Combobox.prototype.getSelfValue = function() {	
	if ( zxt.util.notValue(this.val()) ){
		return "";
	};
	
	var val = this.val();
	if(this.$TextTransform=="uppercase"){
			val = val.toUpperCase();
	};	
	return val;	
};

/**
 * <p>如果参数没上送，则返回当前的自动显示设置；否则，设置自动显示标志</p>
 * @param  {boolean} v 自动显示参数
 * @return {boolean} 如果参数没上送，则返回当前的自动显示设置
 */
zxt.ui.Combobox.prototype.autoShow = function(v){
	if(v===undefined){return this._autoShow;}
	this._autoShow = v;
};

/**
 * <p>如果参数没上送，则返回当前的值的格式设置；否则，设置值的格式 格式类型如N(4) A(20)</p>
 * @param  {String} v 值的格式
 * @return {String} 如果参数没上送，则返回当前的显示格式设置
 */
zxt.ui.Combobox.prototype.formatType = function(f){
	if (zxt.util.isAvailable(f)) {this._formatType=f};
	return this._formatType;
}

/**
 * <p>添加选项后调用的方法，未实现 需要时重载
 * </p>
 * @function
 * @param {object} opt 添加的选项
 */

zxt.ui.Combobox.prototype.afterOptionAdded = function(opt){
	
};

/**
 * <p>如果上送值有对应的配置项描述，则返回之；否则，返回上送的值</p>
 * @param {Stirng} val 上送值
 * @return {String} 如果上送值有对应的配置项描述，则返回之；否则，返回上送的值
 */
zxt.ui.Combobox.prototype._getText = function(val) {
	var opt = this.getOptionByValue(val);//zxt.ui.AbstractSelect 通过值寻找对应的标签
	if(zxt.util.isValue(opt)){
		return this.getOptionText(opt);	//zxt.ui.AbstractSelect 获取配置项描述	
	}; 
	
	if ( zxt.util.notValue(val) ){
		return "";
	};
	
	return val;		
};

/**
 * <p>获取标签寻找对应的值</p>
 * @private
 * @function
 * @param {String} text 标签内容
 * @returns {String} 标签对应的值;若没有找到，则返回上送的参数内容
 */
zxt.ui.Combobox.prototype._getValue = function(text) {
	var opt = this.getOptionByLabel(text); //zxt.ui.AbstractSelect 通过标签寻找对应的值
	if (zxt.util.isValue(opt)){
		return opt.value;
	};
	return text;
};	

/**
 * <p>验证值的合法性, 只有合法的值才会被保存</p>
 * @private 
 * @function
 * 
 */
zxt.ui.Combobox.prototype._decorateV = function() {
	this._$input.removeClass("zxt-txhint");

	var iVal = this.val();
	var opt = this.getOptionByValue(iVal);
	var iLabel = this.getLabel();
	
	this._$input.val(iLabel);
	
	this._$input.removeClass("zxt-txerror").removeClass("zxt-txpass");	
	if ( !zxt.util.isAvailable(iLabel) ) {
		this._$input.addClass("zxt-txhint");
		if (this._required) {	
			this._$input.addClass("zxt-txmust");
			this.validateStatus(false,zxt.core.ValidatorType.REQUIRED); //zxt.ui.Widget
		} else { 
			this._$input.addClass("zxt-txnormal"); 
			this.validateStatus(true);
		};
		return;
	}	
	
	if (!zxt.util.isAvailable(iVal)) {
		if (this.$RequireV) {	
			this._$input.addClass("zxt-txmust");
			this.validateStatus(false,zxt.core.ValidatorType.REQUIRED);
		} else { 
			this._$input.addClass("zxt-txnormal"); 
			this.validateStatus(true);
		};
		return;	
	};
	
	this._$input.removeClass("zxt-txmust").removeClass("zxt-txnormal");

	if ( !this._chooseonly){
		if (!zxt.util.utilsFormat(this.val(),this.formatType())) {
			this._$input.removeClass("zxt-txpass").addClass("zxt-txerror");	
			this.validateStatus(false,zxt.core.ValidatorType.FORMAT,this.formatType());
		}else{
			this._$input.addClass("zxt-txpass").removeClass("zxt-txerror");	
			this.validateStatus(true);
		}
	} else {
		if (zxt.util.isValue(opt)) {
				this._$input.addClass("zxt-txpass").removeClass("zxt-txerror");	
				this.validateStatus(true);					
		} else {
			this._$input.addClass("zxt-txerror").removeClass("zxt-txpass");
			this.validateStatus(false,zxt.core.ValidatorType.LIST,this.formatType());
		};		
	};	
};

/**
 * @private
 * @return
 */
zxt.ui.Combobox.prototype._renderTextbox = function(){
	var instance = this;
	
	this._$input = $("<input type='text' class='zxt-textbox' /> ");	
	var textBox = this._$input;
	var oldSuggestions = $.data(textBox, this._suggestionsKey);
	$.data(textBox, this._suggestionsKey, this._labels);

	// exit if already initialized
	if (oldSuggestions)
		return;
	
	if ( zxt.util.isValue(this.$TextTransform) ){
		this._$input.css("text-transform", this.$TextTransform);
	};
	if ( zxt.util.isValue(this.$MaxLength) ){
		this._$input.attr("maxLength", this.$MaxLength);
	};
	if (zxt.util.isAvailable(this.id()) && zxt.cfg.nameNative) {
		textBox.attr("name", this.id());
	};

	textBox.width("100%");	
	textBox.attr('autocomplete', 'off');	
	textBox.focus(function() {instance.onInputFocus();}).blur(function(){instance.onInputBlur();});	
	textBox.keydown(function(event){instance.keydown(event);}).keyup(function(event){instance.keyup(event);})
	textBox.change(function(){instance.onInputChange();});
	
	this._oldVal=textBox.val();
	
	this._container = textBox.wrap('<div class="combobox" />').parent();
	
};

/**
 * <p>
 * 渲染该组合输入框的DOM节点
 * </p>
 * 
 * @function
 * @return {DOM} 渲染成的DOM节点
 */
zxt.ui.Combobox.prototype.renderSelf = function() {	
	var instance = this;
	var val = this.val();
		
	if ( this._$jqDom == null ){
		this._$jqDom = $("<div nowrap class='zxt-Element'>");
	} else {
		this._$jqDom.empty();	
	};

	this._createLabels();
	this._renderOptionsContainer();
	this._renderTextbox();

	this._decorateV();

	if(this.mode() == "DISABLE" ){
		this._$input.removeClass();
		this._$input.attr("disabled",true);
	}else if(this.mode() =="READONLY"){
		this._$input.removeClass();
		this._$input.attr("readonly",true);
	}else{
		this._$input.attr("disabled",false);
		this._$input.attr("readonly",false);
	};
	
	

	this._$jqDom.append(this._$input);
	return this._$jqDom.get(0);
};

/**
 *  <p>打开下拉框</p>
 * @param {String} filter 过滤器
 * @return
 */
zxt.ui.Combobox.prototype.show = function(filter) {
	if(this.options()==null||this.options().length==0){
		var composite = zxt.data.parseOptions(this._elem);
		composite.loadToSelect(this);
		this.render();
	}
	var textBox = this._$input;
	var instance = this;
	
	this._oriValue = textBox.val();
	this._hideOptions();

	this._optsn = [];
	// generate the options (li inside ul)
	var html = '';
	var suggestions = $.data(textBox, this._suggestionsKey);
	for ( var i=0; i<suggestions.length;i++) {
		var v = suggestions[i];
		var vl = v.toLowerCase();
		if (!filter){
			html += '<li>' + v + '</li>';
			this._optsn.push(this._options[i]);	
		} else {			
			if ( (this.$AutoComplete == 0) && (vl.indexOf(filter.toLowerCase()) >= 0) ){
				html += '<li>' + v + '</li>';
				this._optsn.push(this._options[i]);	
			} else if ( (this.$AutoComplete == 1) && (vl.indexOf(filter.toLowerCase()) == 0) ){
				html += '<li>' + v + '</li>';
				this._optsn.push(this._options[i]);	
			};	
		}	
	}	
	this._optionsContainer.html(html);

	// decide which option is currently selected
	
	var found = false;
	this._selIndex = 0;
	var options = this._optionsContainer.children('li').each(
		function(i) {
			if (found)return;
			if ($(this).text().toLowerCase() == instance._oriValue.toLowerCase()) {
				$(this).addClass('selected');
				instance._selIndex = i;
				found = true;
			}
		});
		
		
	// if there is no items matched, hide the empty
	// select list, so user can show options with
	// down key
	if (!options.size()) {
		return;
	}
	if (!found)options.eq(0).addClass('selected');

	var tt = function(opt, idx) {    
		this.onclick = function() {
			instance._onOptionClick(opt, idx);
		};
	};
	
	for (i = 0; i != options.size(); i++) {		
		var opt = this._optsn[i];			
		var wa = new tt(opt, i);
		$(options[i]).click( wa.onclick );		
	};
	
	options.hover(function() {
		options.each(function() {
			$(this).removeClass('selected');
		});
		$(this).addClass('selected');
		instance._selIndex = options.index(this);
	});
	
	this._expandOptions(this._$input.get(0));
}

/**
 * <p>键盘按下事件处理方法</p>
 * @function
 * @param {Event} evt 键盘事件
 * @return
 */
zxt.ui.Combobox.prototype.keydown = function(evt) {
	var keys = this._keys;
	switch (evt.keyCode) {
	case keys.esc:
		this._hideOptions();
		evt.preventDefault();
		break;
	case keys.enter:
		this.choose();
		evt.preventDefault();
		break;
 	case keys.tab: 
 		this._hideOptions();
 		evt.preventDefault();
		break;
	case keys.up:
		this.goup();
		evt.preventDefault();
		break;
	case keys.down:
		this.godown();
		evt.preventDefault();
		break;
	}
};

/**
 * 
 * <p>键盘按起事件处理方法</p>
 * @param {Event} evt 键盘事件，目前未使用
 * @return
 */
zxt.ui.Combobox.prototype.keyup = function(evt) {
	var v = this._$input.val();
	if (v != this._oldVal) {
		this._oldVal = v;
		this.show(this._oldVal);
	}
	evt.preventDefault();
};

/**
 * <p>显示选中的下拉列表某项内容</p>
 * @function
 * @return
 */
zxt.ui.Combobox.prototype.choose = function() {
	if(this._optsn.length!=0){
		var v = this._optsn[this._selIndex];
		this._$input.val(this.getOptionText(v));
		this._hideOptions();
		this.onInputChange();
	}
};

/**
 * @private
 * @function
 * @param ivalue
 * @return
 */
zxt.ui.Combobox.prototype._complete = function(ivalue){
	for(var i=0;i<this.options().length;i++){
		if(this.options()[i].value == ivalue){
			return this.getOptionText(this.options()[i]);
		}
	};
	return "";
};

/**
 * <p>设置并校验选中的下拉表选项</p>
 * @param {String} opt 配置项 
 * @return
 */
zxt.ui.Combobox.prototype.selectOption = function(opt) {
	this.setValue(opt.value );
	this._oldVal = this.getOptionText(opt);
	this._decorateV();
};

/**
 * @private
 * @event
 * 选择器获得焦点事件
 */
zxt.ui.Combobox.prototype.onInputFocus = function() {
	this.onFocus();
};
/**
 * <p>选择器失去焦点事件</p>
 * @private
 * @function
 * 
 */
zxt.ui.Combobox.prototype.onInputBlur = function() {
	this.onBlur();
};

/**
 * <p>选择器值改变事件</p>
 * @private
 * @function
 * 
 */
zxt.ui.Combobox.prototype.onInputChange = function() {
	var ivalue = this._$input.val();
	var val = this._getValue(ivalue);
	this._oldVal = ivalue;	
	this.setValue(val);
	this._decorateV();	
};

zxt.ui.Combobox.prototype._onOptionClick = function(opt, idx){
	this.selectOption(opt);
	this._hideOptions();
};

zxt.ui.Combobox.prototype.beforeGetValue = function() {
	if ( zxt.util.isValue(this._$input) ){
		this.onInputChange();
	}
};

/**
 * <p>设置当前控件焦点</p>
 * 
 * @function
 * @returns {int} 0
 */
zxt.ui.Combobox.prototype.focusSelf = function(){
	this._$input.focus();
	this._$input.select();
};

/**
 * <p>选择器失去焦点事件</p>
 * @private
 * @function
 * 
 */
zxt.ui.Combobox.prototype.blurSelf = function(){
	this._$input.blur();
	//this.onChange();
};

zxt.ui.Combobox.prototype.whenFocus = function() {
	this._$input.removeClass("zxt-txhint");
	if(this.autoShow() &&this.mode() != "READONLY"){
		this.show('');
	}
};

zxt.ui.Combobox.prototype.whenBlur = function() {
	 if ( this._overOpts || this._hoverTimer )
		 return;		
	this._blur();	
};

/**
 * <p>组合输入框工厂类</p>
 * @class 
 */
zxt.ui.ComboboxFactory = function() {
	zxt.ui.InteractorFactory.call(this);
};

zxt.defineClazz(zxt.ui.ComboboxFactory, zxt.ui.InteractorFactory);

/**
 * <p>获取相应的组合输入框实例对象</p>
 * 
 * @function
 * @return {zxt.ui.Combobox} 输入框实例对象
 */
zxt.ui.ComboboxFactory.prototype.getInstance = function() {
	return new zxt.ui.Combobox();	
};	

/**
 * <p>表示一个Listbox对象</p>
 * @class 
 * @param {boolean} [Multiple] 指定listbox是否为多选, 未指定时默认为true
 * @param {Arraylist} [defaultvalues] 指定listbox的初始化时的默认选中的值 传入一个value数组
 * @param {Boolean} [labelonly] 是否只显示标签 默认是true 
 */

zxt.ui.Listbox = function( Multiple, defaultvalues,labelonly) {
	zxt.ui.AbstractSelect.call(this);
	
	//this._options = [];
	this._checkedRows = [];
	
	if(Multiple==null){
		this._multiple = true;
	}
	else{
		this._multiple = Multiple;
	};
	this._$table = $("<table rules='none'></table>");
	this._defaultvalues = defaultvalues;
	this._labelonly = labelonly==false?false:true;
	
	if(this._labelonly==false){
		this.$Format = "$VALUE$ $LABEL$";
	};
	
	this._$jqDom = $("<div nowrap overflow='auto' class='zxt-Element'>");
	this._$jqInner = null;

};

/**
 * <p>根据传入的DOM元素, 解析传入的相关属性, 创建相应的Listbox对象</p>
 * 
 * @function
 * @static
 * @param {boolean} [zxt.multiple] 指定listbox是否为多选, 未指定时默认为true
 * @param {string} [zxt.labelonly] 是否只显示标签 默认是true
 * @param {string} [zxt.value] 设置默认值
 * @param {string} [zxt.options] 选项 格式为“选项1:选项1的值,选项2:选项2的值,选项3:选项3的值” 
 * @param {string} [zxt.service] 后台加载服务的名称 
 * @param {string} [zxt.method] 后台加载调用的函数名 
 * @param {string} [zxt.param] 后台加载函数的参数 
 * @param {string} [zxt.option] 选项的值 
 * @param {string} [zxt.label] 选项的标签 
 * @param {DOM} elem 解析的DOM元素
 * @return {zxt.ui.Listbox} 根据传入的DOM元素创建的Listbox对象
 */
zxt.ui.Listbox.parse = function(elem) {
	var j = $(elem);	
	var Multiple = j.attr("zxt.multiple");
	var _labelonly = j.attr("zxt.labelonly")=="false"? false:true;
	
	var _instance = new zxt.ui.Listbox(Multiple,null,_labelonly);
	
	var composite = zxt.data.parseOptions(elem);//将dom节点转化为选项
	composite.loadToSelect(_instance);//将数据内容加载到下拉列表中
		
	return _instance;
};

zxt.defineClazz(zxt.ui.Listbox, zxt.ui.AbstractSelect);
zxt.ui.Listbox.prototype.conf = zxt.ui.AbstractSelect.prototype.conf;

/**
 * <p>返回控件类型</p>
 * 
 * @function
 * @returns {string} "zxt.ui.Listbox"
 */
zxt.ui.Listbox.prototype.getType = function() {
	return "zxt.ui.Listbox";
};

/**
 * <p>添加一个选项</p>
 * 
 * @function
 * @param {string} value 在getValue()时返回的选项列表实际的值
 * @param {string} label 选项列表显示的标签
 */

zxt.ui.Listbox.prototype.afterOptionAdded = function(opt){

	
};

/**
 * <p>渲染Listbox的选项</p>
 * @private
 * @function
 * @return
 */
zxt.ui.Listbox.prototype._optionsRender =  function(){
	var instance = this;
	var fc = this._options.length;
	this._$table.empty();
	this._createLabels();
	for(var i=0;i<this._options.length;i++){
		var opt = this._options[i];
		
		this._$table.append("<tr><td>" + this._labels[i] + "</td></tr>");
		
		var $newRow = this._$table.find("tr:last-child");
		$newRow.click(function(event) {
			instance._rowClick(this);
		});
		$newRow.hover(function() {
			if(instance._focusCurrent!=-1){
				instance._removeRowClass(instance._focusCurrent);
			}
			instance._focusCurrent = fc;
			$(this).addClass("zxt-listbox-row-hover");
		}, function() {
			instance._focusCurrent=-1;
			$(this).removeClass("zxt-listbox-row-hover");
		});
	};
};

/**
 * <p>返回Listbox中被选中选项的值</p>
 * 
 * @function
 * @returns {Arraylist} val 被选中选项的值的链表
 */
zxt.ui.Listbox.prototype.getValue = function() {
	var val = [];
	for (index in this._checkedRows) {
		id = this._checkedRows[index].rowIndex;
		option = this._options[id];
		val.push(option.value);
	};
	return val;
};

/**
 * <p>单击选项事件</p>
 * @private
 * @function
 * 
 */
zxt.ui.Listbox.prototype._rowClick = function(row) {
	for (i in this._checkedRows) {
		if (this._multiple == false) {
			$(this._checkedRows[i]).removeClass("zxt-listbox-row-selected");
			delete this._checkedRows[i];
		} else {
			if (this._checkedRows[i].rowIndex == row.rowIndex) {
				delete this._checkedRows[i];
				$(row).removeClass("zxt-listbox-row-selected");
				return;
			}
		}
	};
	this._checkedRows.push(row);
	$(row).addClass("zxt-listbox-row-selected");
};


/**
 * <p>渲染选中项的颜色</p>
 * @private
 * @function
 * 
 */
zxt.ui.Listbox.prototype._addRowClass = function(i){
	this._$table.find("tr").each(function(index){
  		if(index==i){
  			$(this).addClass("zxt-listbox-row-hover");
  		}
  	});
};


/**
 * <p>移除选中项的颜色渲染</p>
 * @private
 * @function
 * 
 */
zxt.ui.Listbox.prototype._removeRowClass = function(i){
		this._$table.find("tr").each(function(index){
  		if(index==i){
  			$(this).removeClass("zxt-listbox-row-hover");
  		}
 	  });
	};


/**
 * <p>截获键盘事件</p>
 * @private
 * @event
 * 
 */
zxt.ui.Listbox.prototype.filterKeyDown = function(keyCode){
	var host = this;
	switch(keyCode)
	{
		case 9:
						this.focus();
						this.setParentFocusState();
						break;
		case 13:
						if(host._focusCurrent!=-1){
							this._$table.find("tr").each(function(index){
								if(index==host._focusCurrent){
									$(this).click();
								}
							});
						}
						break;
		case 38:
						host.lastFocus();
						break;
		case 40:
						host.nextFocus();
						break;
	}
};

/**
 * <p>设置当前控件焦点</p>
 * 
 * @function
 * @returns {int} 0
 */
zxt.ui.Listbox.prototype.focus = function(){
 	retrun -1;
};
 
/**
 * <p>设置当前控件失去焦点事件</p>
 * 
 * @function
 * @returns {int} 0
 */
zxt.ui.Listbox.prototype.blur = function(){
	this._removeRowClass(this._focusCurrent);
	this._focusCurrent=-1;
	return -1;
};
 
/**
 * <p>设置下一个焦点</p>
 * @function
 * @return
 */
zxt.ui.Listbox.prototype.nextFocus = function(){
	if(this._options.length==0){
		return 0;
	}
	if(this._focusCurrent>=this._options.length-1)
	{
		return 0;
	}
	this._focusCurrent++;
	
	if(this._focusCurrent!=0){
		this._removeRowClass(this._focusCurrent-1);
	}
	this._addRowClass(this._focusCurrent);
 };
 
 /**
  * <p>设置上一个焦点</p>
  * @function
  * @return
  */
zxt.ui.Listbox.prototype.lastFocus = function(){
	if(this._focusCurrent<=0)
	{
		return 0;
	}
	if(this._options.length==0){
		return -1;
	}
	this._focusCurrent--;
	
	if(this._focusCurrent==-1){
		this._removeRowClass(0);
		return -1;
	}
	if(this._focusCurrent!=this._options.length-1){
		this._removeRowClass(this._focusCurrent+1);
	}
	this._addRowClass(this._focusCurrent);
	return 1;
 };

/**
 * <p>
 * 渲染该多选框的DOM节点
 * </p>
 * 
 * @function
 * @return {DOM} 渲染成的DOM节点
 */
zxt.ui.Listbox.prototype.renderSelf = function() {
	var instance = this;
	this._$jqDom.empty();
	var table = this._$table;
	this._optionsRender();
	table.addClass("zxt-listbox");
	this._$jqInner = table;
	this._$jqDom.append(this._$jqInner);
	return this._$jqDom.get(0);
};

/**
 * <p>文本框工厂类</p>
 * @class 
 */
zxt.ui.ListboxFactory = function() {
};

zxt.defineClazz(zxt.ui.ListboxFactory, zxt.ui.InteractorFactory);

/**
 * <p>获取相应的输入框实例对象</p>
 * 
 * @function
 * @return {String} zxt.ui.Listbox实例对象
 */
zxt.ui.ListboxFactory.prototype.getInstance = function() {
	return new zxt.ui.Listbox();
};



/**
 * <p>单选组</p>
 * @class 表示一个单选组对象
 * @param {string} group 指定单选组的组名
 * @param {string} [dfval] 指定单选组默认的选择项
 * 
 */
zxt.ui.Choose = function(group, val) {
	zxt.ui.Composite.call(this);
	zxt.ui.AbstractSelect.call(this);

	this._group = group;
	if ( !zxt.util.isAvailable(group) ){
		this._group = zxt.util.GUID();
	};	
	
	this.val(val);
	if (this.val() == undefined)	this.val(null);
	
	this._$jqDom = null;
	this._$jqInner = null;
	
	this._$layout = null;
	this._radios = {};
};



/**
 * <p>根据传入的DOM元素, 解析传入的相关属性, 创建相应的Choose对象</p>
 * 
 * @function
 * @static
 * @param {string} zxt.group 指定单选组的组名
 * @param {string} [zxt.default] 指定单选组默认的选择项
 * @param {string} [zxt.options] 选项 格式为“选项1:选项1的值,选项2:选项2的值,选项3:选项3的值” 
 * @param {string} [zxt.service] 后台加载服务的名称 
 * @param {string} [zxt.method] 后台加载调用的函数名 
 * @param {string} [zxt.param] 后台加载函数的参数 
 * @param {string} [zxt.option] 选项的值 
 * @param {string} [zxt.label] 选项的标签 
 * @param {DOM} elem 解析的DOM元素
 * @return {zxt.ui.Choose} 根据传入的DOM元素创建的Listbox对象
 */
zxt.ui.Choose.parse = function(elem) {
	var j = $(elem);
	var _group = j.attr("zxt.group");
	var _default = j.attr("zxt.default");

	var _instance = new zxt.ui.Choose(_group, _default);	
	
	var options = [];
	var composite = zxt.data.parseOptions(elem);
	composite.loadTo(options);
	for(var i = 0;i<options.length;i++){
		_instance.appendOption(options[i]);
	};
	
	
	if (options.length<=0 && j.children().length>0){
		var _layout = $("<div>");
		_layout.append(j.children());
		_instance.setLayout(_layout);
	}
	
	return _instance;
};

zxt.defineClazz(zxt.ui.Choose, zxt.ui.Composite, zxt.ui.AbstractSelect);
zxt.ui.Choose.prototype.focus = zxt.ui.Composite.prototype.focus;
zxt.ui.Choose.prototype.blur = zxt.ui.Composite.prototype.blur;
zxt.ui.Choose.prototype.onFocus = zxt.ui.Composite.prototype.onFocus;
zxt.ui.Choose.prototype.onBlur = zxt.ui.Composite.prototype.onBlur;
zxt.ui.Choose.prototype.conf = zxt.ui.AbstractSelect.prototype.conf;

/**
 * <p>返回控件类型</p>
 * 
 * @function
 * @returns {string} "zxt.ui.Choose"
 */
zxt.ui.Choose.prototype.getType = function(){
	return "zxt.ui.Choose";
};	

/**
 * <p>获取选择的属性值</p>
 * @function
 * @return
 */
zxt.ui.Choose.prototype.getSelfLabel = function(){
	
	if ( this._$layout == null ){
		return zxt.ui.AbstractSelect.prototype.getSelfLabel.call(this);
	};	
		
	return this.getValue();		
};

/**
 * <p>添加一个选项</p>
 * 
 * @function
 * @param {string} value 在getValue()时返回的选项列表实际的值
 * @param {string} label 选项列表显示的标签
 */
zxt.ui.Choose.prototype.addOption = function(value, label) {
	var opt = {};
	opt.label =label;
	opt.value =value;	
	this._options.push(opt);
	//this._focusOrder = this._childern;
};

/**
 * <p>
 * 设置该单选框选项的JQUERY对象
 * </p>
 * @private
 * @function
 * 
 */
zxt.ui.Choose.prototype.setLayout = function(l) {
	if (typeof l == "string") {
		this._$layout = $("#" + l);
		if (this._$layout.length == 0) {
			throw new Error("Can NOT load Element with ID " + l);
		}
	} else {
		this._$layout = l;
	};
};


/**
 * <p>获取选中项的值</p>
 * 
 * @function
 * @returns {string} v 返回的值
 * 
 */
zxt.ui.Choose.prototype.beforeGetValue = function() {	
	if(this.mode()=="MASK"||this.mode()=="LABEL"){
		return;
	}
	var val = this.val();
	for ( var v in this._radios) {
		var t = this._radios[v];
		var cked = t.getValue();
		if (cked) {
			val = v;
		};
	};
	
	this.val(val);
};


/**
 * <p>
 * 渲染该单选框的DOM节点
 * </p>
 * 
 * @function
 * @return {DOM} 渲染成的DOM节点
 */
zxt.ui.Choose.prototype.renderSelf = function() {	
	
	if ( this._$jqDom == null ) {
		this._$jqDom = $("<div style=\"position: relative;\"/>");
	};	
		
	if ( this._$layout == null ){
		return this._renderBasic();
	};
	return this._renderLayout();	
};	

zxt.ui.Choose.prototype.onChildValueChange = function(child, old, now) {
	this.getValue();	
	return false;	
};


/**
 * <p>
 * 渲染该单选框选项的DOM节点
 * </p>
 * @private
 * @function
 * @return {DOM} 渲染成的DOM节点
 */
zxt.ui.Choose.prototype._renderBasic = function() {
		
	if (this._$jqInner == null || this._rebuild) {
		var count = this._options.length;	
		var tablePanel = new zxt.ui.TablePanel(1, count);	
		var tablePanelDom = tablePanel.render();	
		
		for (i = 0; i != count; i++) {		
			var opt = this._options[i];
			var radio = new zxt.ui.Radiobox(this._group);
			this.addChild(radio);
			
			if (opt.value == this.val())
					radio.setValue(true);
			var radioDom = radio.render();
			
			var optPanel = new zxt.ui.TablePanel(1, 2);	
			var optDom = optPanel.render();
			$(optPanel.getCell(0, 1)).text(opt.label);	
			$(optPanel.getCell(0, 0)).append(radioDom);			
			$(tablePanel.getCell(0, i)).append(optDom);			
			
			this._radios[opt.value] = radio;	
			this._$jqInner = $(tablePanelDom);
			this._$jqDom.append(this._$jqInner);	
		};	
	}else {		
		
		for(var k in this._radios){
			this._radios[k].propagation(false);			
			this._radios[k].renderValue(false);	
			this._radios[k].propagation(true);			
		};
		
		var radio = this._radios[this.val()];
		if (radio) {
			radio.propagation(false);
			radio.renderValue(true);
			radio.propagation(true);
		};
	};	
	return this._$jqDom.get(0);
};	


/**
 * <p>
 * 渲染该单选框选项的DOM节点
 * </p>
 * @private
 * @function
 * @return {DOM} 渲染成的DOM节点
 */
zxt.ui.Choose.prototype._renderLayout = function() {
	var host = this;

	if (this._$jqInner == null || this._rebuild) {
		$("div", this._$layout).each(function(idx, dom) {
			var jdom = $(dom);			
			var _value = jdom.attr("option");
			
			if ( zxt.util.isValue(_value) ){			
				var _radio = new zxt.ui.Radiobox(host._group);	
				host.addChild(_radio);
						
				if (_value == host.val())
					_radio.val(true);
				$(dom).append(_radio.render());				
				
				host._radios[_value] = _radio;			
			}
		});
		this._$jqInner = this._$layout;
		this._$jqDom.append(this._$jqInner);

		this._rebuild = false;
	} else {
		
		for(var k in this._radios){
			this._radios[k].propagation(false);			
			this._radios[k].renderValue(false);	
			this._radios[k].propagation(true);			
		};
		
		var radio = this._radios[this.val()];
		if (radio) {
			radio.propagation(false);
			radio.renderValue(true);
			radio.propagation(true);
		};
	};

	return this._$jqDom.get(0);
};


/**
 * <p>下拉框工厂类</p>
 * @class 
 */
zxt.ui.ChooseFactory = function() {
	zxt.ui.InteractorFactory.call(this);
};

zxt.defineClazz(zxt.ui.ChooseFactory, zxt.ui.InteractorFactory);

/**
 * <p>获取相应的下拉框实例对象</p>
 * 
 * @function
 * @return 下拉框实例对象
 */
zxt.ui.ChooseFactory.prototype.getInstance = function() {
	return new zxt.ui.Choose();
};

/**
 * <p>符号控件</p> 
 * @class
 * @extends zxt.ui.AbstractSelect zxt.ui.Element
 */
zxt.ui.Symbol = function(){
	zxt.ui.AbstractSelect.call(this);
	zxt.ui.Element.call(this);
	
	this._labelonly = true;
	this._current = 0;
	
	this._jqDom = $("<div nowrap>");
	this._jqInner = new zxt.ui.Icon();
			
	this.$Height = "100%";
	this.$Width = "100%";
};

/**
 * <p>根据传入的DOM元素, 解析传入的相关属性, 创建相应的Symbol对象</p>
 * @function
 * @param {DOM} elem DOM节点
 * @return
 */
zxt.ui.Symbol.parse = function(elem) {
	var j = $(elem);

	var _instance = new zxt.ui.Symbol();
	var composite = zxt.data.parseOptions(elem);
	composite.loadToSelect(_instance);
	return _instance;
};

zxt.defineClazz(zxt.ui.Symbol, zxt.ui.AbstractSelect, zxt.ui.Element);
zxt.ui.Symbol.prototype.getSelfLabel = zxt.ui.Element.prototype.getSelfLabel;
zxt.ui.Symbol.prototype.conf = zxt.ui.AbstractSelect.prototype.conf;

/**
 * <p>返回控件类型</p>
 * 
 * @function
 * @returns {string} "zxt.ui.Symbol"
 */
zxt.ui.Symbol.prototype.getType = function() {
	return "zxt.ui.Symbol";
};

/**
 * <p>如果参数未上送，则返回当前的显示符号图片的索引；否则，重新设置当前显示符号图片的索引</p>
 * @param {int} v 显示符号图片的索引
 * @return {int} 如果参数未上送，则返回当前的显示符号图片的索引
 */
zxt.ui.Symbol.prototype.current = function(v){
	if(v===undefined){
		if(zxt.util.isAvailable(this.getValue())){
			for(var t=0;t<this.options().length;t++){
				if(this.options()[t].value == this.getValue()){
					this._current = t;
				}
			}
		};
		return this._current;
	}
	this.val(this.options()[v].value);
	this._current = v;
};

/**
 * <p>渲染DOM节点</p>
 * @function
 * @return
 */
zxt.ui.Symbol.prototype.renderSelf = function(){
	var host = this;
	this._jqDom.empty();
	
	this._jqInner.height(this.$Height).width(this.$Width);
	this._jqInner.image(this.options()[host.current()].label);
	if(this.mode() != "DISABLE" && this.mode() !="READONLY"){
		this._jqInner.clickFunc(function(){host.changeImg();});//关联单击方法，用于更换显示图片
	};
	
	this.val(this.options()[host.current()].value);
	this._jqDom.append(this._jqInner.render());
	return this._jqDom;
};

/**
 * <p>更换显示符号图片</p>
 * @function
 * @return
 */
zxt.ui.Symbol.prototype.changeImg = function(){
	var host = this;
	var i = this.current();
	i++;
	i = i%this.options().length;
	this._jqInner.image(this.options()[i].label);
	this._jqInner.render();
	this.current(i);
	this.val(this.options()[host.current()].value);
};

zxt.cfg.Sign = {
	IMG$Plus     : zxt.cfg.IMAGES_PATH + '/plus.png',
	IMG$Minus    : zxt.cfg.IMAGES_PATH + '/minus.png'	
};

/**
 * <p>正负号控件</p>
 * @class
 * @extends zxt.ui.Symbol
 */
zxt.ui.Sign = function(){
	zxt.ui.Symbol.call(this);
};

/**
 * <p>返回控件类型</p>
 * 
 * @function
 * @returns {string} "zxt.ui.Sign"
 */
zxt.ui.Sign.prototype.getType = function() {
	return "zxt.ui.Sign";
};

zxt.defineClazz(zxt.ui.Sign, zxt.ui.Symbol);

/**
 * <p>根据传入的DOM元素, 解析传入的相关属性, 创建相应的Sign对象</p>
 * @function
 * @param {DOM} elem DOM节点
 * @return
 */
zxt.ui.Sign.parse = function(elem) {
	var j = $(elem);

	var _instance = new zxt.ui.Sign();
	var plus = {value:'+', label:zxt.cfg.Sign.IMG$Plus};
	var minus = {value:'-', label:zxt.cfg.Sign.IMG$Minus};
	_instance.appendOption(plus);
	_instance.appendOption(minus);
	
	return _instance;
};